package cn.jbit.houserent.dao.hibimpl;

import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;
import org.hibernate.Transaction;
import org.hibernate.criterion.Example;
import cn.jbit.houserent.bean.House;
import cn.jbit.houserent.bean.User;
import cn.jbit.houserent.dao.BaseHibernateDAO;
import cn.jbit.houserent.dao.HouseDao;
import cn.jbit.houserent.util.QueryProperties;

/**
 * @author zhiyao.xi
 *
 */
public class HouseDaoHibImpl extends BaseHibernateDAO implements HouseDao {
	private static final Log log = LogFactory.getLog(HouseDaoHibImpl.class);

	/* (non-Javadoc)
	 * @see cn.jbit.houserent.dao.HouseDao#save(cn.jbit.houserent.bean.House)
	 */
	public void save(House transientInstance) {
		log.debug("saving House instance");
		Transaction tx = null;
		try {
			tx = getSession().beginTransaction();
			getSession().save(transientInstance);
			tx.commit();
			log.debug("save successful");
		} catch (RuntimeException re) {
			tx.rollback();
			log.error("save failed", re);
			throw re;
		} finally{
			closeSession();
		}
	}

	/* (non-Javadoc)
	 * @see cn.jbit.houserent.dao.HouseDao#delete(cn.jbit.houserent.bean.House)
	 */
	public void delete(House persistentInstance) {
		log.debug("deleting House instance");
		Transaction tx = getSession().beginTransaction();
		try {
			getSession().delete(persistentInstance);
			tx.commit();
			log.debug("delete successful");
		} catch (RuntimeException re) {
			tx.rollback();
			log.error("delete failed", re);
			throw re;
		} finally{
			closeSession();
		}
	}

	/* (non-Javadoc)
	 * @see cn.jbit.houserent.dao.HouseDao#findById(java.lang.Integer)
	 */
	public House findById(java.lang.Integer id) {
		log.debug("getting House instance with id: " + id);
		try {
			House instance = (House) getSession().get(
					"cn.jbit.houserent.bean.House", id);
			return instance;
		} catch (RuntimeException re) {
			log.error("get failed", re);
			throw re;
		} finally{
			closeSession();
		}
		
	}

	/* (non-Javadoc)
	 * @see cn.jbit.houserent.dao.HouseDao#findByExample(cn.jbit.houserent.bean.House)
	 */
	@SuppressWarnings("unchecked")
	public List<House> findByExample(House instance) {
		log.debug("finding House instance by example");
		List<House> results = null;
		try {
		    results = getSession().createCriteria("cn.jbit.houserent.bean.House").add(Example.create(instance)).list();
		    return results;
		} catch (RuntimeException re) {
			return results;
		} finally{
			closeSession();
		}
		
	}

	/* (non-Javadoc)
	 * @see cn.jbit.houserent.dao.HouseDao#findByProperty(java.lang.String, java.lang.Object)
	 */
	@SuppressWarnings("unchecked")
	public List<House> findByProperty(String propertyName, Object value) {
		log.debug("finding House instance with property: " + propertyName
				+ ", value: " + value);
		try {
			String queryString = "from House as model where model."
					+ propertyName + "like ?";
			Query queryObject = getSession().createQuery(queryString);
			queryObject.setParameter(0, "%"+value+"%");
			return queryObject.list();
		} catch (RuntimeException re) {
			log.error("find by property name failed", re);
			throw re;
		} finally{
			closeSession();
		}
		
	}
	
	/* (non-Javadoc)
	 * @see cn.jbit.houserent.dao.HouseDao#findByProperty(java.lang.String, java.lang.Object)
	 */
	@SuppressWarnings("unchecked")
	public List<House> findByHQL(String hql) {
		log.debug("finding House instance with hql: " + hql);
		try {
			Query queryObject = getSession().createQuery(hql);
			return queryObject.list();
		} catch (RuntimeException re) {
			log.error("find by property name failed", re);
			throw re;
		} finally{
			closeSession();
		}
		
	}

	/* (non-Javadoc)
	 * @see cn.jbit.houserent.dao.HouseDao#findAll()
	 */
	@SuppressWarnings("unchecked")
	public List<House> findAll() {
		log.debug("finding all House instances");
		try {
			String queryString = "from House";
			Query queryObject = getSession().createQuery(queryString);
			queryObject.setMaxResults(5);
			return queryObject.list();
		} catch (RuntimeException re) {
			log.error("find all failed", re);
			throw re;
		} finally{
			closeSession();
		}
	}
	
	/* (non-Javadoc)
	 * @see cn.jbit.houserent.dao.HouseDao#findHouseByProperties(cn.jbit.houserent.util.QueryProperties)
	 */
	@SuppressWarnings("unchecked")
	public List<House> findHouseByProperties(QueryProperties qp){
		log.debug("finding  House by properties");
		
		try {

			StringBuffer queryString = new StringBuffer();
			queryString.append("from House where ");
			
			queryString.append("(title like :title) ");
			
			//queryString.append("and (price between :low_price and :high_price) ");
			//queryString.append("and (street_id like :street_id) ");
			//queryString.append("and (type_id like :type_id) ");
			queryString.append("and (floorage between :small_floorage and :big_floorage) ");
			//queryString.append("and (date between :start_date and :end_date)");
			System.out.println(queryString.toString());
			Query queryObject = getSession().createQuery(queryString.toString());
			queryObject.setProperties(qp);
			return queryObject.list();
		} catch (RuntimeException re) {
			log.error("find house by properties failed", re);
			throw re;
		} finally{
			closeSession();
		}

	}

	public void update(House transientInstance) {
		log.debug("updating House instance");
		Transaction tx = getSession().beginTransaction();
		try {
			getSession().update(transientInstance);
			tx.commit();
			log.debug("update successful");
		} catch (RuntimeException re) {
			tx.rollback();
			log.error("update failed", re);
			throw re;
		} finally{
			closeSession();
		}
		
	}
}